package com.main.usermanagement.interfaces.facade;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.main.common.base.resp.RespBody;
import com.main.common.interfaces.PreventShaking;
import com.main.usermanagement.application.service.RegisterService;
import com.main.usermanagement.application.service.UserService;
import com.main.usermanagement.domain.user.aggregate.User;
import com.main.usermanagement.interfaces.dto.RegisterDTO;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

@Tag(name = "Register", description = "注册用户")
@RestController
@RequestMapping("")
@Slf4j
public class RegisterFacade {
    @Resource
    private RegisterService registerService;
    @Resource
    private UserService userService;
    // 定义锁容器
    private static final Map<String, ReentrantLock> PHONE_LOCKS = new ConcurrentHashMap<>();


    @PostMapping("/register")
    @PreventShaking(keys = "registerDTO.phone&registerDTO.email.value", prefix = "register", expire = 30)
    public RespBody<User> register(@Validated @RequestBody RegisterDTO registerDTO) throws JsonProcessingException {
        // 获取锁
        ReentrantLock lock = PHONE_LOCKS.computeIfAbsent(registerDTO.getPhone(), k -> new ReentrantLock());
        lock.lock();
        try {
            List<User> userList = userService.findByPhone(registerDTO.getPhone());
            if (!userList.isEmpty()) {
                return RespBody.fail(userList.size() > 1 ? "手机号被重复注册" : "手机号已被注册");
            }
            return registerService.register(registerDTO);
        } finally {
            lock.unlock();
            // 原子性清理锁（仅当无持有时移除）
            PHONE_LOCKS.computeIfPresent(registerDTO.getPhone(), (k, v) -> {
                log.info("LOCK{}{}",k, v);
                if (v.getHoldCount() == 0) {
                    return null; // 移除锁
                }
                return v; // 保留锁
            });
        }
     }


    @PostMapping("/test")
    @PreventShaking(keys = "name", prefix = "test", expire = 2)
    public RespBody<String> test(@Validated @RequestBody String name) throws JsonProcessingException {
        System.out.println("time"+LocalDateTime.now());
        return RespBody.ok(name);
    }
}
